package com.yanjiali.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yanjiali.mappers.RecordPersonalHistoricalRecordsReqMapper;
import com.yanjiali.model.R;
import com.yanjiali.model.req.RecordPersonalHistoricalRecordsReq;
import com.yanjiali.model.resp.ObtainTheHistoricalRecordsTo5ThroughTheUserIdResp;
import com.yanjiali.model.resp.RecordPersonalHistoricalRecordsResq;
import com.yanjiali.model.resp.SearchHistoryByTitleResp;
import com.yanjiali.vo.HistoricalRecordMonthVO;
import com.yanjiali.vo.HistoricalRecordYearVO;
import com.yanjiali.vo.HistoricalRecordsOfTheDayVO;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yanjiali.entity.History;
import com.yanjiali.mapper.HistoryMapper;
import com.yanjiali.service.HistoryService;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Package: com.yanjiali.service.impl
 * @Author: yanjiali
 * @Created: 2025/4/19 15:06
*/
@Service
public class HistoryServiceImpl extends ServiceImpl<HistoryMapper, History> implements HistoryService{

    @Override
    public R<RecordPersonalHistoricalRecordsResq> recordPersonalHistoricalRecords(RecordPersonalHistoricalRecordsReq recordPersonalHistoricalRecordsReq) {
        History history = RecordPersonalHistoricalRecordsReqMapper.INSTANCE.entity2Resp(recordPersonalHistoricalRecordsReq);

        String title = history.getTitle();
        LambdaQueryWrapper<History> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(History::getTitle, title);
        History one = getOne(lambdaQueryWrapper);
        if(one == null) {   //不存咋的历史插入
            boolean save = save(history);
            if(save) {
                return R.ok(new RecordPersonalHistoricalRecordsResq("记录历史成功"));
            }
        }else { //已经存在的历史修改时间即可
            history.setCreateTime(new Date());  //TODO 公共字段填充中修改不会动创建时间
            LambdaUpdateWrapper<History> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(History::getTitle, one.getTitle());
            boolean update = update(history, lambdaUpdateWrapper);
            if(update) {
                return R.ok(new RecordPersonalHistoricalRecordsResq("记录历史成功"));
            }
        }

        return R.fail(new RecordPersonalHistoricalRecordsResq("记录历史失败"));
    }

    @Override
    public R<ObtainTheHistoricalRecordsTo5ThroughTheUserIdResp> obtainTheHistoricalRecordsTo5ThroughTheUserId() {
        //获取登录用户的id
        String userId = null;
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication != null) {
            userId = authentication.getPrincipal().toString();
        }else {
            throw new RuntimeException("未登录的用户查询历史");
        }

        //构建查询条件并查询
        LambdaQueryWrapper<History> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(History::getCreateBy, userId)
                .orderByDesc(History::getCreateTime)
                .last("limit 5");
        List<History> historyList = list(lambdaQueryWrapper);
        if(historyList != null || historyList.size() > 0) {
            List<String> titles = historyList.stream()
                    .map(history -> history.getTitle()).collect(Collectors.toList());

            return R.ok(new ObtainTheHistoricalRecordsTo5ThroughTheUserIdResp(titles));
        }
        return R.fail("查询失败");
    }

    @Override
    public R<HistoricalRecordYearVO> obtainTheCurrentYearsHistoricalRecords() {
        //首先从数据库里面获取所有数据
        String userId = null;
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication != null) {
            userId = authentication.getPrincipal().toString();
        }else {
            throw new RuntimeException("未登录的用户查询历史");
        }

        LambdaQueryWrapper<History> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        String[] currentYearArea = getCurrentYearArea();
        lambdaQueryWrapper
                .eq(History::getCreateBy, userId)
                .ge(History::getCreateTime, currentYearArea[0])
                .lt(History::getCreateTime, currentYearArea[1])
                //TODO 增加条件
                .orderByDesc(History::getCreateTime);

        List<History> list = list(lambdaQueryWrapper);

        if(list == null || list.size() < 1) {
            return R.fail("当前用户没有历史记录");
        }

        //然后进行封装整合
        HistoricalRecordYearVO historicalRecordYearVO = packageTheCurrentYearsData(list);

        return R.ok(historicalRecordYearVO);
    }

    @Override
    public R<SearchHistoryByTitleResp> searchHistoryByTitle(String title) {
        String userId = null;
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication != null) {
            userId = authentication.getPrincipal().toString();
        }else {
            throw new RuntimeException("未登录的用户查询历史");
        }

        LambdaQueryWrapper<History> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper
                .eq(History::getCreateBy, userId)
                .like(History::getTitle, title);

        List<History> historyList = list(lambdaQueryWrapper);

        if(historyList == null || historyList.size() < 1) {
            return R.fail("当前用户没有对应历史记录");
        }

        return R.ok(new SearchHistoryByTitleResp(historyList));
    }

    @Override
    public R deleteInBatches(List<Long> ids) {
        if(ids == null || ids.size() < 1) {
            throw new IllegalArgumentException("不合法的参数，传递的ids为空或者没有值");
        }

        String userId = null;
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication != null) {
            userId = authentication.getPrincipal().toString();
        }else {
            throw new RuntimeException("未登录的用户查询历史");
        }

        LambdaUpdateWrapper<History> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper
                .in(History::getId, ids)
                .eq(History::getCreateBy, userId);

        boolean remove = remove(lambdaUpdateWrapper);

        if(remove) {
            return R.ok("批量删除成功");
        }

        return R.fail("批量删除失败");
    }

    @Override
    public R deleteOneByOne(Long id) {
        //TODO 如果对应模块jdk版本更高可以使用List.of
        List<Long> list = new ArrayList<>();
        list.add(id);
        if(deleteInBatches(list).getCode() == 200) {
            return R.ok("删除成功");
        }

        return R.fail("删除失败");
    }

    @Override
    public R deleteAll() {
        String userId = null;
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication != null) {
            userId = authentication.getPrincipal().toString();
        }else {
            throw new RuntimeException("未登录的用户查询历史");
        }

        LambdaUpdateWrapper<History> lambdaUpdateWrapper = new LambdaUpdateWrapper();
        lambdaUpdateWrapper.eq(History::getCreateBy, userId);

        boolean remove = remove(lambdaUpdateWrapper);
        if(remove) {
            return R.ok("清空历史记录成功");
        }

        return R.fail("清空历史记录失败");
    }

    /**
     * 获取当前年份区间字符串数组
     * @return
     */
    private String[] getCurrentYearArea() {
        // 获取当前年份
        int currentYear = LocalDate.now().getYear();

        // 获取今年起始 与 明年起始
        LocalDateTime currentYearStart = LocalDateTime.of(currentYear, 1, 1, 0, 0, 0);
        LocalDateTime nextYearStart = currentYearStart.plusYears(1L);

        // 定义日期时间格式化器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        return new String[]{currentYearStart.format(formatter), nextYearStart.format(formatter)};
    }

    /**
     * 封装当前年数据
     * 优化：如果当前天，当天月，当前年没有任何数据则剔除记录
     * 为了使其倒置，遍历从尾部开始
     * @return
     */
    private HistoricalRecordYearVO packageTheCurrentYearsData(List<History> list) {
        LocalDate currentDate = LocalDate.now();

        //封装年
        int year = currentDate.getYear();
        HistoricalRecordYearVO historicalRecordYearVO = new HistoricalRecordYearVO();
        historicalRecordYearVO.setTimeString(year + "");
        int currentYearNum = 0;

        HistoricalRecordMonthVO historicalRecordMonthVO = null;
        for (int month = 12; month >= 1; month--) {     //封装月
            historicalRecordMonthVO = new HistoricalRecordMonthVO();
            historicalRecordMonthVO.setTimeString(month + "");
            int currentMonthNum = 0;

            YearMonth yearMonth = YearMonth.of(year, month);
            int daysInMonth = yearMonth.lengthOfMonth();    //通过年月获取对应天数

            HistoricalRecordsOfTheDayVO historicalRecordsOfTheDayVO = null;
            for(int day = daysInMonth; day >= 1; day--) {   //封装天
                final int m = month, d = day;

                historicalRecordsOfTheDayVO = new HistoricalRecordsOfTheDayVO();
                historicalRecordsOfTheDayVO.setTimeString(day + "");
                int currentDayNum = 0;

                for(History history : list) {
                    LocalDate localDate = LocalDate.of(year, m, d);
                    LocalDate comparedLocalDate = history.getCreateTime().toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalDate();
                    if(localDate.equals(comparedLocalDate)) {   //是当前天的数据
                        currentDayNum++;    //更新天条数
                        historicalRecordsOfTheDayVO.getHistoryList().add(history);
                    }
                }

                if(currentDayNum > 0) { //对应天有记录才记录
                    historicalRecordMonthVO.getDayList().add(historicalRecordsOfTheDayVO);    //将对应天数据添加到月
                }
                currentMonthNum += currentDayNum;   //更新月条数
            }

            if(currentMonthNum > 0) {   //对应月有记录才记录
                historicalRecordYearVO.getMonthList().add(historicalRecordMonthVO);  //对应月数据添加到年
            }
            currentYearNum += currentMonthNum;
        }

        return currentYearNum > 0 ? historicalRecordYearVO : null;  //对应年有数据才返回
    }
}
